package com.roc.admin.application.service.impl;

import com.roc.admin.application.service.UserService;
import com.roc.admin.domain.entity.User;
import com.roc.admin.domain.repository.UserRepository;
import com.roc.admin.domain.service.UserDomainService;
import com.roc.admin.domain.valueobject.UserPermission;
import com.roc.admin.interfaces.dto.UserDTO;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserDomainService userDomainService;
    private final UserRepository userRepository;


    @Override
    @Transactional
    public Long createUser(UserDTO userDTO) {
        User user = toUser(userDTO);
        user = userDomainService.createUser(user);
        return user.getId();
    }

    @Override
    @Transactional
    public boolean updateUser(UserDTO userDTO) {
        User user = toUser(userDTO);
        user = userDomainService.updateUser(user);
        return user != null;
    }

    @Override
    @Transactional
    public boolean deleteUser(Long userId) {
        userDomainService.deleteUser(userId);
        return true;
    }

    @Override
    public UserDTO getUserById(Long userId) {
        Optional<User> userOptional = userRepository.findById(userId);
        return userOptional.map(this::toUserDTO).orElse(null);
    }

    @Override
    public UserDTO getUserByUsername(String username) {
        Optional<User> userOptional = userRepository.findByUsername(username);
        return userOptional.map(this::toUserDTO).orElse(null);
    }

    @Override
    public List<UserDTO> getUserList() {
        List<User> userList = userRepository.findAll();
        return userList.stream().map(this::toUserDTO).collect(Collectors.toList());
    }

    @Override
    public List<UserDTO> getUserListByDeptId(Long deptId) {
        List<User> userList = userRepository.findByDeptId(deptId);
        return userList.stream().map(this::toUserDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        return userDomainService.changePassword(userId, oldPassword, newPassword);
    }

    @Override
    @Transactional
    public boolean resetPassword(Long userId, String newPassword) {
        userDomainService.resetPassword(userId, newPassword);
        return true;
    }

    @Override
    public Set<UserPermission> getUserPermissions(Long userId) {
        return userDomainService.getUserPermissions(userId);
    }

    @Override
    @Transactional
    public boolean assignRoles(Long userId, List<Long> roleIds) {
        userDomainService.assignRoles(userId, roleIds);
        return true;
    }

    @Override
    public User login(String username, String password) {
        Optional<User> userOptional = userRepository.findByUsername(username);
        if (userOptional.isEmpty()) {
            return null;
        }

        User user = userOptional.get();
        // 密码验证逻辑应该在领域服务中实现
        // 这里简化处理，实际应该调用领域服务的方法
        if (!user.isEnabled()) {
            return null;
        }

        // 假设有一个密码编码器实现
        if (!user.checkPassword(password, new PasswordEncoderImpl())) {
            return null;
        }

        return user;
    }

    /**
     * 将用户DTO转换为用户实体
     *
     * @param userDTO 用户DTO
     * @return 用户实体
     */
    private User toUser(UserDTO userDTO) {
        if (userDTO == null) {
            return null;
        }
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        return user;
    }

    /**
     * 将用户实体转换为用户DTO
     *
     * @param user 用户实体
     * @return 用户DTO
     */
    private UserDTO toUserDTO(User user) {
        if (user == null) {
            return null;
        }
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }

    /**
     * 密码编码器实现类
     */
    private static class PasswordEncoderImpl implements User.PasswordEncoder {
        @Override
        public String encode(String rawPassword) {
            // 实际项目中应该使用更安全的加密算法，如BCrypt
            return rawPassword;
        }

        @Override
        public boolean matches(String rawPassword, String encodedPassword) {
            // 实际项目中应该使用更安全的验证方法
            return encode(rawPassword).equals(encodedPassword);
        }
    }
}
